<!-- 音频可视化组件 -->
<template>
  <view class="audio-visualizer-container">
    <!-- 长方形可视化区域 -->
    <view class="bar-visualizer-container">
      <view 
        v-for="(height, index) in visualizerBars" 
        :key="index" 
        class="visualizer-bar" 
        :style="{ 
          width: barWidth + 'px',
          height: height * fadeFactors[index] + 'px',
          backgroundColor: getBarColor(index, height),
          marginLeft: index > 0 ? barMargin + 'px' : '0',
          bottom: '0px'
        }"
      ></view>
    </view>
    
    <!-- 调试信息 -->
    <view class="visualizer-debug" v-if="showDebug">
      <text>可视化条数量: {{ visualizerBars.length }}</text>
      <text>最大高度: {{ Math.max(...visualizerBars) || 0 }}</text>
      <text>平均高度: {{ visualizerBars.reduce((a, b) => a + b, 0) / visualizerBars.length || 0 }}</text>
      <text v-if="fadeOutTimer">淡出倒计时: {{ (1000 - (Date.now() - fadeOutStartTime)) / 1000 | number(1) }}s</text>
    </view>
  </view>
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'

// 可视化配置
const props = defineProps({
  audioData: {
    type: Uint8Array,
    required: true
  },
  isPlaying: {
    type: Boolean,
    default: false
  },
  barCount: {
    type: Number,
    default: 64
  },
  // 新增：接收音频上下文实例（用于恢复播放）
  audioContext: {
    type: Object,
    default: null
  }
})

const barWidth = ref(6)
const barMargin = ref(2)
const visualizerBars = ref(Array(props.barCount).fill(10)) // 初始高度
const fadeFactors = ref(Array(props.barCount).fill(1)) // 淡出因子（控制显示）
const animationId = ref(null)
const showDebug = ref(false)
const lastHeights = ref(Array(props.barCount).fill(10)) // 平滑过渡用
const fadeOutTimer = ref(null) // 淡出计时器ID
const fadeOutStartTime = ref(0) // 记录淡出倒计时开始时间
const isFadingOut = ref(false) // 是否正在淡出

// 颜色生成
const getBarColor = (index, height) => {
  const baseColors = [
    'rgba(64, 158, 255, ',
    'rgba(103, 194, 58, ',
    'rgba(230, 162, 60, ',
    'rgba(245, 108, 108, ',
    'rgba(156, 89, 218, '
  ];
  const alpha = 0.6 + (height / 255) * 0.4;
  return baseColors[index % baseColors.length] + alpha + ')'
}

// 动画主循环
const updateVisualization = () => {
  if (!props.audioData || props.audioData.length === 0) {
    visualizerBars.value = visualizerBars.value.map(h => h + (Math.random() - 0.5) * 5);
  } else {
    const newBars = [];
    const dataLength = props.audioData.length;
    
    for (let i = 0; i < props.barCount; i++) {
      const dataIndex = i % dataLength;
      const value = props.audioData[dataIndex];
      
      const targetHeight = value * 0.5; // 音频条浮动长度
      const currentHeight = lastHeights.value[i] || 10;
      const smoothFactor = props.isPlaying ? 0.3 : 0.1; // 音频条浮动频率速度
      const smoothedHeight = currentHeight + (targetHeight - currentHeight) * smoothFactor;
      
      newBars.push(Math.max(5, smoothedHeight));
      lastHeights.value[i] = smoothedHeight;
    }
    visualizerBars.value = newBars;
  }
  
  // 处理淡出动画
  if (isFadingOut.value) {
    updateFadeFactors();
  }
  
  animationId.value = requestAnimationFrame(updateVisualization);
}

// 启动淡出倒计时（停止播放时）
const startFadeOutTimer = () => {
  if (fadeOutTimer.value) clearTimeout(fadeOutTimer.value);
  fadeOutStartTime.value = Date.now(); // 记录开始时间
  // 5秒后开始淡出
  fadeOutTimer.value = setTimeout(() => {
    isFadingOut.value = true;
    fadeOutTimer.value = null;
  }, 5000);
}

// 停止淡出（恢复播放时）
const stopFadeOutTimer = () => {
  if (fadeOutTimer.value) {
    clearTimeout(fadeOutTimer.value);
    fadeOutTimer.value = null;
  }
  // 强制重置所有淡出状态（关键修复：确保动画恢复）
  isFadingOut.value = false;
  fadeFactors.value = Array(props.barCount).fill(1); // 重置透明度为1
  // 恢复音频上下文（如果存在）
  if (props.audioContext && props.audioContext.state === 'suspended') {
    props.audioContext.resume().catch(err => {
      console.warn('恢复音频上下文失败:', err);
    });
  }
}

// 从上到下淡出效果
const updateFadeFactors = () => {
  let allFaded = true;
  const fadeSpeed = 0.05;
  
  fadeFactors.value = fadeFactors.value.map((factor, index) => {
    if (factor > 0) {
      // 上方条形先淡出（索引小的先变化）
      const newFactor = Math.max(0, factor - (fadeSpeed * (1 + index / props.barCount)));
      allFaded = allFaded && newFactor === 0;
      return newFactor;
    }
    return factor;
  });
  
  if (allFaded) {
    // 全部淡出后重置基础高度
    visualizerBars.value = Array(props.barCount).fill(10);
    lastHeights.value = Array(props.barCount).fill(10);
    isFadingOut.value = false;
  }
}

// 监听播放状态变化（核心修复：确保恢复时重置状态）
watch(() => props.isPlaying, (newVal) => {
  console.log('播放状态变化:', newVal ? '播放' : '暂停');
  if (newVal) {
    // 恢复播放时强制重置动画状态
    stopFadeOutTimer();
    // 手动触发一次动画更新（确保立即显示）
    nextTick(() => {
      if (animationId.value) {
        cancelAnimationFrame(animationId.value);
      }
      updateVisualization();
    });
  } else {
    startFadeOutTimer();
  }
}, { immediate: true }); // 立即执行一次，同步初始状态

// 其他生命周期和监听
onMounted(() => {
  const container = document.querySelector('.bar-visualizer-container');
  if (container) {
    const containerWidth = container.clientWidth;
    const maxBarWidth = Math.floor((containerWidth - (props.barCount - 1) * barMargin.value) / props.barCount);
    barWidth.value = Math.min(10, maxBarWidth);
  }
  updateVisualization();
})

onUnmounted(() => {
  if (animationId.value) cancelAnimationFrame(animationId.value);
  if (fadeOutTimer.value) clearTimeout(fadeOutTimer.value);
})

watch(() => props.barCount, (newBarCount) => {
  visualizerBars.value = Array(newBarCount).fill(10);
  lastHeights.value = Array(newBarCount).fill(10);
  fadeFactors.value = Array(newBarCount).fill(1);
})
</script>

<style scoped>
/* 样式保持不变 */
.audio-visualizer-container {
  width: 100%;
  padding: 15px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
}

.bar-visualizer-container {
  width: 100%;
  height: 180px;
  /* background-color: rgba(0, 0, 0, 0.05); */
  display: flex;
  align-items: flex-end;
  justify-content: center;
  border-radius: 8px;
  /* box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); */
}

.visualizer-bar {
  position: relative;
  border-radius: 3px 3px 0 0;
  transition: height 0.05s ease-out;
  box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
}

.visualizer-debug {
  margin-top: 10px;
  padding: 5px 10px;
  background-color: rgba(0, 0, 0, 0.7);
  color: white;
  font-size: 12px;
  border-radius: 5px;
  width: 100%;
  text-align: center;
}
</style>